<template>
  <div>
    <div ref="modelContainer" class="model-container">
      <div v-if="loadingProgress < 100">
        <v-progress-circular
          class="progress-container"
          :size="300"
          :width="25"
          :value="loadingProgress"
          indeterminate
        >
          <div style="text-align: center;">
            <div style="font-size:35px; color:#9daed7; margin-bottom:10px;">
              模型加载中...
            </div>
            <div style="font-size:50px; color:#9daed7;">
              {{ Math.round(loadingProgress) }}%
            </div>
          </div>
        </v-progress-circular>
      </div>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';


import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// import Vuetify from 'vuetify/lib';
// import resize from './mixins/resize';

export default {
  name: 'ThreedModel',
  components: {
    // Vuetify
  },
  // mixins: [resize],
  data() {
    return {
      modelContainer: null,
      loadingProgress: 0,
      buffer: new Uint8Array(0),
      isParsing: false,
      baseModelLoaded: false,
      animationLoaded: false,
      scene: null,
      camera: null,
      renderer: null,
      model: null,
      controls: null,
      mixer: null, // 用于处理动画
      clock: null, // 用于控制动画的时间
    };
  },
  mounted() {
    console.log('ThreedModel mounted');
    this.initThree();
    this.load3DModel();
    window.addEventListener('resize', this.onWindowResize);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.onWindowResize);
  },
  methods: {
    initThree() {
      console.log('Initializing Three.js');
      this.scene = new THREE.Scene();
      this.camera = new THREE.PerspectiveCamera(75, this.$refs.modelContainer.clientWidth / this.$refs.modelContainer.clientHeight, 0.1, 1000);
      this.camera.position.set(0, 0, 10);

      this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
      this.renderer.setSize(this.$refs.modelContainer.clientWidth, this.$refs.modelContainer.clientHeight);
      this.renderer.setClearColor(0xADD8E6, 0);
      // this.renderer.domElement.style.pointerEvents = 'none';
      this.$refs.modelContainer.appendChild(this.renderer.domElement);

      const light = new THREE.DirectionalLight(0xffffff, 1);
      light.position.set(5, 3, 5);
      this.scene.add(light);

      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.update();

      this.clock = new THREE.Clock(); // 初始化时钟

      const animate = () => {
        requestAnimationFrame(animate);
        if (this.mixer) this.mixer.update(this.clock.getDelta()); // 更新动画
        this.controls.update();
        this.renderer.render(this.scene, this.camera);
      };

      animate();
    },

    fitToScreen() {
      const box = new THREE.Box3().setFromObject(this.model);
      const size = box.getSize(new THREE.Vector3());
      const center = box.getCenter(new THREE.Vector3());

      this.model.position.x = -center.x;
      this.model.position.y = -center.y;
      this.model.position.z = -center.z;
      // this.model.rotation.y = THREE.MathUtils.degToRad(-30); // 绕 Y 轴旋转 90 度

      const maxSize = Math.max(size.x, size.y, size.z);
      // const fitHeightDistance = maxSize / (2 * Math.atan((Math.PI * this.camera.fov) / 360));
      // const fitWidthDistance = fitHeightDistance / this.camera.aspect;
      // const distance = fitWidthDistance > fitHeightDistance ? fitWidthDistance : fitHeightDistance;

      this.camera.position.set(0, 0, 9); // 给出一些额外的空间
      // this.camera.position.set(0, 0, distance * 1.2); // 给出一些额外的空间
      this.camera.lookAt(center);
    },

    load3DModel() {
      this.loadingProgress = 0;
      console.log('Loading 3D model');
      const modelPath = require('@/assets/threedmodel/mesmodel.glb'); // 确保路径正确
      const dracoLoader = new DRACOLoader();
      dracoLoader.setDecoderPath('@/lib/draco/');
      dracoLoader.setWorkerLimit(4);
      const loader = new GLTFLoader();
      loader.setDRACOLoader(dracoLoader);

      loader.load(modelPath, (gltf) => {
        console.log('GLTF loaded successfully:', gltf);
        dracoLoader.dispose();

        this.model = gltf.scene;
        this.scene.add(this.model);
        // 调整模型位置和缩放
        // this.model.scale.set(1.5, 1.5, 1.5);
        // this.model.position.set(0, -5, 0);

        // this.camera.position.set(0, 0, 10);
        // this.camera.lookAt(this.scene.position);
        
        this.fitToScreen();
        // 创建动画混合器
        this.mixer = new THREE.AnimationMixer(this.model);

        // 获取模型中的所有动画
        const animations = gltf.animations;
        if (animations && animations.length > 0) {
          // 假设我们只播放第一个动画
          const clip = animations[0];
          const action = this.mixer.clipAction(clip);
          action.play(); // 开始播放动画
        }
      }, 
      (xhr) => {
        this.loadingProgress = (xhr.loaded / xhr.total) * 100;
        // console.log('Loading progress:', this.loadingProgress);
      }, 
      undefined, (error) => {
        console.error('Error loading 3D model:', error);
      });
    },

    onWindowResize() {
      this.camera.aspect = this.$refs.modelContainer.clientWidth / this.$refs.modelContainer.clientHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(this.$refs.modelContainer.clientWidth, this.$refs.modelContainer.clientHeight);
    }
  }
}
</script>

<style scoped>
.model-container {
  width: 2000px;
  height: 1200px;
  left: -75%;
  position: relative;
  background-color: transparent;
  z-index: 0;
  margin: 0 auto;

  top: 18%;
  transform: translateY(-18%);
}

.progress-container {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 280px;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #9daed7 !important;
}
</style>

<!-- //   async load3DModel() {
  //     try {
  //       const modelPath = require('@/assets/threedmodel/mesmodel.glb'); // 确保路径正确

  //       // ===== 1. 初始化带Draco的加载器 =====
  //       const dracoLoader = new DRACOLoader();
  //       dracoLoader.setDecoderPath('/lib/draco/'); // 指向public目录
  //       dracoLoader.setWorkerLimit(4);

  //       const loader = new GLTFLoader();
  //       loader.setDRACOLoader(dracoLoader);

  //       // ===== 2. 获取模型总大小 =====
  //       const totalSize = await this.getFileSize(modelPath);
  //       let offset = 0;

  //       // ===== 3. 动态分块加载 =====
  //       while (offset < totalSize) {
  //         const chunkSize = this.calculateChunkSize();
  //         const end = Math.min(offset + chunkSize, totalSize);

  //         const chunk = await this.fetchChunk(modelPath, offset, end);
  //         this.buffer = this.mergeBuffers(this.buffer, new Uint8Array(chunk));
  //         offset = end;

  //         // ===== 4. 触发流式解析 =====
  //         if (!this.isParsing) {
  //           this.isParsing = true;
  //           await this.tryParseStream(loader);
  //         }

  //         // 更新加载进度
  //         this.loadingProgress = (offset / totalSize) * 100;
  //       }
  //     } catch (error) {
  //       console.error('模型加载失败:', error);
  //       this.retryLoading();
  //     }
  //   },

  //   // ========== 核心工具方法 ==========
  //   async getFileSize(url) {
  //     const res = await fetch(url, { method: 'HEAD' });
  //     return parseInt(res.headers.get('Content-Length'));
  //   },

  //   async fetchChunk(url, start, end) {
  //     try {
  //       end = Math.min(end, this.totalSize);
  //       const res = await fetch(url, {
  //         headers: { 'Range': `bytes=${start}-${end - 1}` }
  //       });
        
  //       if (!res.ok) {
  //         throw new Error(`分块请求失败: ${res.status}`);
  //       }
        
  //       const chunk = await res.arrayBuffer();
  //       console.log(`成功加载分块 ${start}-${end}`);
  //       return chunk;
  //     } catch (error) {
  //       console.error(`分块加载错误: ${error.message}`);
  //       throw error;
  //     }
  //   },

  //   // 修改mergeBuffers方法，避免内存重复累积
  //   mergeBuffers(existing, newChunk) {
  //     // 使用Transferable对象提升性能
  //     const temp = new Uint8Array(existing.length + newChunk.length);
  //     temp.set(existing, 0);
  //     temp.set(newChunk, existing.length);
      
  //     // 释放旧内存
  //     existing = null; 
  //     newChunk = null;
      
  //     return temp;
  //   },

  //   async tryParseStream(loader) {
  //     try {
  //       // 校验数据完整性
  //       if (this.buffer.length < 20) return; // 等待更多数据
        
  //       const dataView = new DataView(this.buffer.buffer);
  //       const totalLength = dataView.getUint32(12, true) + 20; // 总长度=JSON块长度+头长度
        
  //       // 确保已加载足够数据
  //       if (this.buffer.length < totalLength) return;
        
  //       // 切片出完整GLB部分
  //       const fullGLB = this.buffer.slice(0, totalLength);
  //       this.buffer = this.buffer.slice(totalLength); // 移除已处理部分
        
  //       const gltf = await new Promise((resolve, reject) => {
  //         loader.parse(fullGLB.buffer, '', resolve, reject);
  //       });
        
  //       this.processPartialModel(gltf);
  //     } catch (error) {
  //       // 错误处理...
  //     }
  //   },

  //   processPartialModel(gltf) {
  //     // 首次解析到基础结构
  //     if (!this.baseModelLoaded && gltf.scene) {
  //       this.model = gltf.scene;
  //       this.scene.add(this.model);
  //       this.fitToScreen();
  //       this.baseModelLoaded = true;
  //     }

  //     // 渐进更新材质系统
  //     if (gltf.materials) {
  //       gltf.materials.forEach(newMat => {
  //         const targetMesh = this.model.getObjectByName(newMat.name);
  //         if (targetMesh) {
  //           targetMesh.material = newMat.clone();
  //         }
  //       });
  //     }

  //     延迟加载动画系统
  //     if (!this.animationLoaded && gltf.animations && gltf.animations.length > 0) {
  //     // if (!this.animationLoaded && gltf.animations?.length > 0) {
  //       this.mixer = new THREE.AnimationMixer(this.model);
  //       const clip = gltf.animations.find(a => a.name === 'MainAction');
  //       if (clip) {
  //         const action = this.mixer.clipAction(clip);
  //         action.play();
  //         this.animationLoaded = true;
  //       }
  //     }

  //     // 内存优化：移除已处理数据
  //     if (gltf.parser && gltf.parser.json) {
  //     // if (gltf.parser?.json) {
  //       const processedLength = gltf.parser.json._byteLength;
  //       this.buffer = this.buffer.slice(processedLength);
  //     }
  //   },

  //   // ========== 辅助方法 ==========
  //   // 动态分块算法 (根据可用内存调整)
  //   calculateChunkSize() {
  //     if (window.performance.measure) performance = window.performance.memory;
  //     if (!performance) return 1024 * 1024; // 默认1MB
      
  //     // 计算剩余可用内存
  //     const usedMB = performance.usedJSHeapSize / 1024 / 1024;
  //     const totalMB = performance.jsHeapSizeLimit / 1024 / 1024;
  //     const freeMB = totalMB - usedMB - 100; // 保留100MB安全空间
      
  //     return Math.min(
  //       Math.max(256 * 1024, freeMB * 0.5 * 1024 * 1024), // 使用剩余内存的50%
  //       4 * 1024 * 1024 // 最大4MB
  //     );
  //   },

  //   fitToScreen() {
  //     // 模型自适应屏幕
  //     const box = new THREE.Box3().setFromObject(this.model);
  //     const size = box.getSize(new THREE.Vector3());
  //     const maxDim = Math.max(size.x, size.y, size.z);
  //     const fov = this.camera.fov * (Math.PI / 180);
  //     const cameraZ = Math.abs((maxDim / 2) / Math.tan(fov / 2));

  //     this.camera.position.z = cameraZ * 1.5;
  //     this.camera.lookAt(box.getCenter(new THREE.Vector3()));
  //   },

  //   retryLoading() {
  //     // 重试逻辑
  //     console.log('尝试重新加载...');
  //     setTimeout(() => this.load3DModel(), 3000);
  //   },

  //   animate() {
  //     requestAnimationFrame(this.animate);
  //     if (this.mixer) this.mixer.update(0.016); // 按60fps更新
  //     this.renderer.render(this.scene, this.camera);
  //   }
  // }
  } -->